package com.github.maojx0630.onebot.ws;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.maojx0630.onebot.dto.MsgGroupInfo;
import com.github.maojx0630.onebot.dto.send.Send;
import com.github.maojx0630.onebot.dto.send.SendDto;
import com.github.maojx0630.onebot.dto.send.msg.SendText;
import com.github.maojx0630.onebot.monitor.MonitorFactory;
import com.github.maojx0630.onebot.monitor.MsgGroupMonitor;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author 毛家兴
 * @since 2024-04-01 14:46
 */
@Slf4j
@Getter
@AllArgsConstructor
public class QqBotMessageHandle {

  private MonitorFactory factory;

  public void handle(WebSocketSession ws, String qq, String msg) {
    if (JSON.isValidObject(msg)) {
      log.info("收到消息:{}", msg);
      this.handleMsg(ws, qq, JSON.parseObject(msg, MsgInfo.class));
    } else {
      log.warn("非json格式消息:{}", msg);
    }
  }

  private void handleMsg(WebSocketSession ws, String qq, MsgInfo msg) {
    if (msg == null || StrUtil.isBlank(msg.getPost_type())) {
      return;
    }
    switch (msg.getPost_type()) {
      // 消息类型
      case "message" -> {
        switch (msg.getMessage_type()) {
          // 私聊
          case "private" -> {
          }
          // 群聊
          case "group" -> {
            MsgGroupInfo info = new MsgGroupInfo();
            info.setSocketQq(qq);
            info.setSelf_id(msg.getSelf_id());
            info.setUser_id(msg.getUser_id());
            info.setTime(msg.getTime());
            info.setMessage_id(msg.getMessage_id());
            info.setGroup_id(msg.getGroup_id());
            info.setSend_id(msg.getSender().getUser_id());
            info.setSend_role(msg.getSender().getRole());
            List<MsgInfo.MessageBean> messageBeans = msg.getMessage();
            messageBeans.stream()
                    .filter(item -> "text".equals(item.getType()))
                    .findFirst()
                    .ifPresent(
                            item -> {
                              info.setMessage(item.getData().getText());
                            });
            messageBeans.stream()
                    .filter(item -> "at".equals(item.getType()))
                    .findFirst()
                    .ifPresent(
                            item -> {
                              info.setAt(item.getData().getQq());
                            });
            messageBeans.stream()
                    .filter(item -> "reply".equals(item.getType()))
                    .findFirst()
                    .ifPresent(
                            item -> {
                              info.setReply(item.getData().getId());
                            });

            for (MsgGroupMonitor monitor : factory.getMsgGroupMonitors()) {
              SendDto sendDto = monitor.handle(info);
              if (CollUtil.isNotEmpty(sendDto.getMessage())) {
                List<List<Send>> sends = new ArrayList<>();
                sends.add(new ArrayList<>());
                for (Send send : sendDto.getMessage()) {
                  if ("json".equals(send.getType())) {
                    if (CollUtil.isEmpty(sends.get(sends.size() - 1))) {
                      sends.get(sends.size() - 1).add(send);
                    } else {
                      sends.add(new ArrayList<>(Collections.singletonList(send)));
                    }
                    sends.add(new ArrayList<>());
                  } else {
                    sends.get(sends.size() - 1).add(send);
                  }
                }
                if (CollUtil.isNotEmpty(sends) && CollUtil.isNotEmpty(sends.get(0))) {
                  sendGroupMsg(ws, msg, sends.stream().filter(CollUtil::isNotEmpty).toList(), sendDto.isAt());
                }
              }

            }
          }
          default -> {
            // 暂不处理
          }
        }
      }
      // 通知类型
      case "notice" -> {
        switch (msg.getNotice_type()) {
          // 群成员增加
          case "group_increase" -> {

          }
          // 群成员减少
          case "group_decrease" -> {
          }
          default -> {
          }
        }
      }
      default -> {
        // 其他类型暂不处理
      }
    }
  }

  @SneakyThrows
  private void sendGroupMsg(WebSocketSession ws, MsgInfo msg, List<List<Send>> sendList, boolean isAt) {
    for (int i = 0; i < sendList.size(); i++) {
      List<Send> sends = sendList.get(i);
      if (CollUtil.isNotEmpty(sends)) {
        if (0 != i) {
          Thread.sleep(300L);
        }

        List<JSONObject> messages = new ArrayList<>();
        if (i == 0 && isAt) {
          JSONObject jsonObject = new JSONObject();
          jsonObject.put("type", "at");
          jsonObject.put("data", JSONObject.of("qq", msg.getSender().getUser_id()));
          messages.add(jsonObject);
          sends.add(0, SendText.of("\n"));
        }
        for (Send send : sends) {
          JSONObject jsonObject = new JSONObject();
          jsonObject.put("type", send.getType());
          jsonObject.put("data", JSONObject.of(send.getKey(), send.getValue()));
          messages.add(jsonObject);
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("group_id", msg.getGroup_id());
        jsonObject.put("message", messages);

        JSONObject jsonSend = new JSONObject();
        jsonSend.put("action", "send_group_msg");
        jsonSend.put("params", jsonObject);
        ws.sendMessage(new TextMessage(jsonSend.toString()));
      }
    }

  }
}
